﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using DesignerHelper.Help;
using DesignerHelper.Main;
using SpreadsheetGear;
using SpreadsheetGear.Windows.Forms;

namespace WorkbookDesigner.UI
{
    public partial class LocateRangeDialog : Form
    {
        private LocateRangeDialog()
        {
            InitializeComponent();
        }

        public LocateRangeDialog(WorkbookView wbv) : this()
        {
            ActiveView = wbv;
            if (ActiveView == null)
            {
                MesBox.ErrorMessage("打开窗口出错,请重试");
                return;
            }
            BookWorkOn = ActiveView.ActiveWorkbook;
            LbwTrigger = LockBookWorker.GetWorker(BookWorkOn);
            TriggerInit();
        }

        private WorkbookView ActiveView { get; set; }

        private IWorkbook BookWorkOn { get; set; }
        private Dictionary<int, IName> NamesFound { get; set; }
        private Dictionary<int, IName> IndexOfRange { get; set; }

        private LockBookWorker LbwTrigger { get; set; }

        private string SearchText => textBoxSearch.Text;

        private bool InSearchMode => !string.IsNullOrEmpty(SearchText);

        private Dictionary<int, IName> WorkingDictionary => InSearchMode ? NamesFound : IndexOfRange;

        private void ResetListViewSize(int count)
        {
            listViewNames.VirtualListSize = count;
        }

        private void TriggerInit()
        {
            INames names = BookWorkOn.Names;
            Text = $"名称定位 - {BookWorkOn.Name}";
            ResetRangeIndex(names);
            NamesFound = new Dictionary<int, IName>();
        }

        private void ResetRangeIndex(INames names)
        {
            LbwTrigger.DoWork(() =>
            {
                var dic = names.Cast<IName>()
                    .Where(name => name.Visible && name.RefersToRange != null)
                    .ToDictionary(name => name.Index);
                IndexOfRange = new Dictionary<int, IName>();
                foreach (IName name in names.Cast<IName>().Where(name => name.Visible && name.RefersToRange != null))
                {
                    IndexOfRange.Add(IndexOfRange.Count, name);
                }
                ResetListViewSize(IndexOfRange.Count);
                AutoSizeColumn();
            });
        }

        private ListViewItem GetListViewItem(int index, bool searching)
        {

            IName n;
            if (searching && NamesFound.Count > 0)
                NamesFound.TryGetValue(index, out n);
            else
                IndexOfRange.TryGetValue(index, out n);
            ListViewItem item = null;
            LbwTrigger.DoWork(() =>
            {
                string name = n?.Name ?? "";
                string address = n?.RefersToRange?.GetAddress(true, true, ReferenceStyle.A1, true, null) ?? "";
                item = new ListViewItem(new[] { name, address })
                {
                    Tag = n,
                };
            });
            return item;
        }






        private void SearchTextFilter()
        {
            if (!InSearchMode)
            {
                ResetListViewSize(IndexOfRange.Count);
                return;
            }
            LbwTrigger.DoWork(() =>
            {
                NamesFound.Clear();
                foreach (IName name in IndexOfRange.Values
                    .Where(x => x.Name.ToUpper().Contains(SearchText.ToUpper())))
                {
                    NamesFound.Add(NamesFound.Count, name);
                }
            });
            ResetListViewSize(NamesFound.Count);

        }

        private void AutoSizeColumn()
        {
            columnHeaderAddress.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            columnHeaderNames.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
        }



        #region 响应窗体事件
        private void buttonReset_Click(object sender, EventArgs e)
        {
            TriggerInit();
        }
        private void textBoxSearch_TextChanged(object sender, EventArgs e)
        {
            SearchTextFilter();
        }
        private void listViewNames_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            IName name = e.Item.Tag as IName;
            LbwTrigger.DoWork(() =>
            {
                name?.RefersToRange?.Worksheet.Select();
                name?.RefersToRange?.Select();
            });
        }
        private void listViewNames_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)
        {

        }
        private void LocateRangeDialog_FormClosed(object sender, FormClosedEventArgs e)
        {
            UnhookEvents();
        }


        private void listViewNames_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            e.Item = GetListViewItem(e.ItemIndex, InSearchMode);
        }

        private void HookEvents()
        {
            
            //FileOperator.AllFormsList.CellBeginEditInternal += DisableDialog;
            //FormManager.AllFormsList.CellCancelEditInternal += EnableDialog;
            //FormManager.AllFormsList.CellEndlEditInternal += EnableDialog;
        }

        private void UnhookEvents()
        {
            //FormManager.AllFormsList.CellBeginEditInternal -= DisableDialog;
            //FormManager.AllFormsList.CellCancelEditInternal -= EnableDialog;
            //FormManager.AllFormsList.CellEndlEditInternal -= EnableDialog;

        }
        private void EnableDialog(object sender, EventArgs e)
        {
            textBoxSearch.Enabled = true;
            listViewNames.Enabled = true;
            TriggerInit();
        }

        private void DisableDialog(object sender, EventArgs e)
        {
            textBoxSearch.Enabled = false;
            ResetListViewSize(0);
            listViewNames.Enabled = false;

        }
        private void LocateRangeDialog_Load(object sender, EventArgs e)
        {
            HookEvents();
        }
        private void LocateRangeDialog_Resize(object sender, EventArgs e)
        {
            //ResizeColumn();
            columnHeaderAddress.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
            columnHeaderNames.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
        }
        private void listViewNames_SelectedIndexChanged(object sender, EventArgs e)
        {
            ActiveView.FindForm()?.Activate();
        }

        #endregion

    }


}


